import 'dart:io';
import 'package:cross_file/cross_file.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/models/common/StatusMessageResult.dart';
import 'package:get/get.dart';
import 'package:http_parser/http_parser.dart';
import 'package:ichinesereader/utils/log.dart';

class RecorderServiceProvider extends GetConnect {
  Rx<StatusMessageResult> get statusMessageResult => this._statusMessageResult;
  Rx<StatusMessageResult> _statusMessageResult =
      Rx<StatusMessageResult>(StatusMessageResult());
  StatusMessageResult _statusResult = new StatusMessageResult();

  RecorderServiceProvider() {
    httpClient.addResponseModifier((request, response) {
      if (response.statusCode == 403) {
        Get.snackbar(
            'Message'.tr,
            'You have been logged out due to inactivity or security reasons.'
                .tr,
            backgroundColor: Color(0xff23c6c8),
            colorText: Color(0xffd8ffff),
            snackPosition: SnackPosition.BOTTOM);
        return Get.offAllNamed('/login');
      } else if (response.statusCode == 401) {
        Get.snackbar('Message'.tr, 'Unauthorized access'.tr,
            backgroundColor: Color(0xff23c6c8),
            colorText: Color(0xffd8ffff),
            snackPosition: SnackPosition.BOTTOM);
        return Get.offAllNamed('/login');
      } else {
        Log.debug(response.request?.url.toString());
        return response;
      }
    });
    httpClient.maxAuthRetries = 2;
    httpClient.timeout = Duration(seconds: 30);
  }

  Future<dynamic> getRecording(bookId, assignmentId) async {
    var box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    String studentName = box.get(CacheManagerKey['username']);
    String path =
        '${Constants.BaseAPI}studentmanager/recording/$studentName/$bookId';
    if (assignmentId != '' && assignmentId != null) {
      path =
          '${Constants.BaseAPI}studentmanager/recording/$studentName/$bookId/$assignmentId';
    }

    final response = await get(
      path,
      headers: <String, String>{
        'authtoken': _authtoken,
        'content-type': 'application/json;charset=UTF-8',
      },
    );
    return response;
  }

  Future<dynamic> downloadFileLocation(fileId) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}studentmanager/location/file/$fileId',
      headers: <String, String>{
        'authtoken': _authtoken,
        'content-type': 'application/json;charset=UTF-8',
      },
    );
    return response;
  }

  Future<dynamic> saveRecordFileInBook(path, bookId, assignmentId) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    var uri = Uri.parse('${Constants.BaseAPI}studentmanager/file');
    var request = http.MultipartRequest('POST', uri);
    request.headers.addAll({'authtoken': _authtoken});
    try {
      late var bytes;
      if (path.startsWith('blob:http')) {
        bytes = await XFile(path).readAsBytes();
      } else {
        bytes = await File.fromUri(Uri.parse(path)).readAsBytes();
      }
      request.files.add(http.MultipartFile.fromBytes('file', bytes,
          filename: 'file', contentType: MediaType('audio', 'mpeg')));
      _statusResult = new StatusMessageResult();
      var response = await request.send();
      final respStr = await response.stream.bytesToString();
      var fileId = jsonDecode(respStr)['fileId'];
      if (fileId != null) {
        var data;
        if (assignmentId != '' && assignmentId != null) {
          data = {
            'bookId': bookId,
            'location': fileId,
            'assignmentId': assignmentId
          };
        } else {
          data = {'bookId': bookId, 'location': fileId};
        }
        var response = await post(
          '${Constants.BaseAPI}studentmanager/recording',
          data,
          headers: <String, String>{
            'authtoken': _authtoken,
            'content-type': 'application/json;charset=UTF-8'
          },
        );
        if (response.statusCode == 200) {
          _statusResult.status = 1000;
          _statusResult.message = 'Success';
        } else {
          _statusResult.status = response.statusCode;
          _statusResult.message = 'Failed';
        }
      }
    } catch (error) {
      _statusResult.status = 0;
      _statusResult.message = error.toString();
      print(error);
    }
    _statusMessageResult.value = _statusResult;
  }

  Future<dynamic> shareRecordFileInBook(path, bookId, assignmentId) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    var uri = Uri.parse('${Constants.BaseAPI}studentmanager/file');
    var request = http.MultipartRequest('POST', uri);
    request.headers.addAll({'authtoken': _authtoken});
    late var bytes;
    if (path.startsWith('blob:http')) {
      bytes = await XFile(path).readAsBytes();
    } else {
      bytes = await File.fromUri(Uri.parse(path)).readAsBytes();
    }
    request.files.add(http.MultipartFile.fromBytes('file', bytes,
        filename: 'file', contentType: MediaType('audio', 'mpeg')));
    var response = await request.send();
    final respStr = await response.stream.bytesToString();
    var fileId = jsonDecode(respStr)['fileId'];
    if (fileId != null) {
      // save and share
      var data;
      if (assignmentId != '' && assignmentId != null) {
        data = {
          'bookId': bookId,
          'location': fileId,
          'assignmentId': assignmentId
        };
      } else {
        data = {'bookId': bookId, 'location': fileId};
      }
      await post(
        '${Constants.BaseAPI}studentmanager/recording',
        data,
        headers: <String, String>{
          'authtoken': _authtoken,
          'content-type': 'application/json;charset=UTF-8'
        },
      );
      if (assignmentId != '' && assignmentId != null) {
        sendRecordingToTeacher(bookId, assignmentId);
      } else {
        sendRecordingToParent(bookId);
      }
    }
  }

  Future<dynamic> sendRecordingToParent(bookId) async {
    try {
      _statusResult = new StatusMessageResult();
      var box = Hive.box('appconfig');
      String studentName = box.get(CacheManagerKey['username']);
      var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
      final response = await put(
        '${Constants.BaseAPI}studentmanager/recording/send/$studentName/$bookId',
        jsonEncode({}),
        headers: <String, String>{
          'authtoken': _authtoken,
          'content-type': 'application/json;charset=UTF-8'
        },
      );
      Log.debug('inside parent response ${response.statusCode}');
      if (response.statusCode == 200) {
        _statusResult.status = 1000;
        _statusResult.message = 'Success';
      } else {
        _statusResult.status = response.statusCode;
        _statusResult.message = 'Failed';
      }
    } catch (error) {
      _statusResult.status = 0;
      _statusResult.message = error.toString();
      Log.debug(error);
    }
    _statusMessageResult.value = _statusResult;
  }

  Future<dynamic> sendRecordingToTeacher(bookId, assignmentId) async {
    try {
      _statusResult = new StatusMessageResult();
      final box = Hive.box('appconfig');
      var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
      String studentName = box.get(CacheManagerKey['username']);
      final response = await put(
        '${Constants.BaseAPI}studentmanager/recording/send/$studentName/$bookId/$assignmentId',
        //'${Constants.BaseAPI}studentmanager/recording/send/nhs0a3/6c6c5da5-b1bb-48fd-9574-ca417bdb0e64/59ccfb09-8c53-4b5c-830e-6fdbd2e56054',
        jsonEncode({}),
        headers: <String, String>{
          'authtoken': _authtoken,
          'content-type': 'application/json;charset=UTF-8'
        },
      );
      Log.debug('inside teacher response ${response.statusCode}');
      if (response.statusCode == 200) {
        _statusResult.status = 1000;
        _statusResult.message = 'Success';
      } else {
        _statusResult.status = response.statusCode;
        _statusResult.message = 'Failed';
      }
    } catch (error) {
      _statusResult.status = 0;
      _statusResult.message = error.toString();
      Log.debug(error);
    }
    _statusMessageResult.value = _statusResult;
  }
}
